﻿#rem monkeydoc module fontmachine.bitmapfont
	This module contains the BitmapFont class.
	This class is the most important class in the FontMachine library as this class is, itself, a font.
	All FontMachine bitmap fonts are instances od a BitmapFont class.
#end
Import mojo.graphics
Import mojo.app 
'Import mojo.input 
Import fontmachine.fontmachine
Import fontmachine.bitmapchar 
Import fontmachine.drawingrectangle 
Import fontinterface
Import fontmachine.edrawalign 
private
Import fontmachine.edrawmode 
public

#rem monkeydoc
	This class represents a BitmapFont.
	A BitmapFont is a font used to draw text on the graphics canvas.
	Usually, to load a FontMachine font in your game or application, all you have to do is:

Global myFont:BitmapFont = BitmapFont.Load("myfont.txt")
myFont.DrawText("Hello world!",10,10)
(Obviously, you better see the complete source code samples)
#end
Class BitmapFont Implements Font
	#rem monkeydoc 
		This function creates an instance of a BitmapFont class.
		The fontName parameter indicates the name of the txt file containing the font description (generated by the FontMachine editor).
		The second parameter indicates if the font should be loaded dynamically (only valid for non packed fonts).
	#end
	Function Load:BitmapFont(fontName:String, dynamicLoad:bool)
		Local font:= new BitmapFont(fontName, dynamicLoad)
		Return font
	End
	
	#rem monkeydoc 
		This is a BitmapFont class constructor.
		The fontDescriptionFilePath parameter indicates the name of the txt file containing the font description (generated by the FontMachine editor).
		The second parameter (dynamicLoad) indicates if the font should be loaded dynamically (only valid for non packed fonts).
	#end
	Method New(fontDescriptionFilePath:String, dynamicLoad:bool)
		local text:String = LoadString(fontDescriptionFilePath)
		if text = "" Then Print "FONT " + fontDescriptionFilePath + " WAS NOT FOUND!!!"
		LoadFontData(text, fontDescriptionFilePath, dynamicLoad )
	End
	
	#rem monkeydoc 
		This is a BitmapFont class constructor.
		The fontDescriptionFilePath parameter indicates the name of the txt file containing the font description (generated by the FontMachine editor).
	#end
	Method New(fontDescriptionFilePath:String)
		local text:String = LoadString(fontDescriptionFilePath)
		if text = "" Then Print "FONT " + fontDescriptionFilePath + " WAS NOT FOUND!!!"
		LoadFontData(text, fontDescriptionFilePath, True )
	End method
	
	#rem monkeydoc 
		Set this property to True or False to enable the font shadow.
		If the font has been rendered without a shadow, this property has no effect.
	#end
	Method DrawShadow:Bool() Property
		Return _drawShadow
	End
	
	Method DrawShadow(value:Bool) property
		_drawShadow = value
	End
	
	#rem monkeydoc
		Set this property to True or False to enable the font border.
		If the font has been rendered without a border, this property has no effect.
	#end
	Method DrawBorder:Bool() Property
		Return _drawBorder
	End
	
	Method DrawBorder(value:Bool) property
		_drawBorder = value
	End
	
	#rem monkeydoc 
		This method will return the image associated to a given char on dynamic fonts.
		If the character image has not been loaded yet, this function will load it.
	#end
	Method GetFaceImage:Image(char:Int) 
		if char>=0 And char<faceChars.Length() Then
			If faceChars[char] = Null Then Return Null
			if faceChars[char].packedFontIndex >0 Then Return packedImages[faceChars[char].packedFontIndex]
			if faceChars[char].CharImageLoaded() = false then faceChars[char].LoadCharImage()
			Return faceChars[char].image
		endif
	End Method
	
	#rem monkeydoc 
		This method will return the image associated to a given char border on dynamic fonts.
		If the character border image has not been loaded yet, this function will load it.
	#end
	Method GetBorderImage:Image(char:Int) 
		if char>=0 And char<borderChars.Length() Then
			If borderChars[char] = Null Then Return Null
			if borderChars[char].packedFontIndex >0 Then Return packedImages[borderChars[char].packedFontIndex]
			if borderChars[char].CharImageLoaded() = false Then borderChars[char].LoadCharImage()
			Return borderChars[char].image
		endif
	End Method

	#rem monkeydoc 
		This method will return the image associated to a given char shadow on dynamic fonts.
		If the character shadow image has not been loaded yet, this function will load it.
	#end
	Method GetShadowImage:Image(char:Int) 
		if char>=0 And char<shadowChars.Length() Then
			If shadowChars[char] = Null Then Return Null
			if shadowChars[char].packedFontIndex >0 Then Return packedImages[shadowChars[char].packedFontIndex]
			If shadowChars[char].CharImageLoaded() = false Then shadowChars[char].LoadCharImage()
			Return shadowChars[char].image
		endif
	End Method
	
	#rem monkeydoc 
		This function return the number of chars that have been created in the given bitmapfont.
		[b]Important:[/b]Notice that some chars can have null characters due them being just part of scape sequences, so be sure to check for <> null before accesing any character info by index.
	#End
	Method CharCount:Int()
		Return Self.faceChars.Length
	End
	

	
	#rem
		summary:This method allows you to draw a string on the graphics canvas.
		This method is a simplified version of the DrawText command that asumes left aligment of text.
	#end
	Method DrawText(text:String, x:Float, y:Float, align:Int)
		'If DrawShadow Then DrawCharsText(text, x, y, eDrawMode.SHADOW, align, 1, -1)
		'If DrawBorder Then DrawCharsText(text, x, y, eDrawMode.BORDER, align, 1, -1)
		'DrawCharsText(text, x, y, eDrawMode.FACE, align, 1, -1)
		DrawText(text, x, y, align, 1, -1)
	End
	
	Method DrawText(text:String, x:Float, y:Float)
		Self.DrawText(text,x,y,eDrawAlign.LEFT )
	End

	Method DrawText(text:String, x:Float, y:Float, align:Int, initChar:Int, endChar:Int)
		If DrawShadow Then DrawCharsText(text, x, y, eDrawMode.SHADOW, align, initChar, endChar)
		If DrawBorder Then DrawCharsText(text, x, y, eDrawMode.BORDER, align, initChar, endChar)
		DrawCharsText(text, x, y, eDrawMode.FACE, align, initChar, endChar)
	End

	
		

	#rem monkeydoc 
		This method returns the width in graphic units of the given string.
	#end
	Method GetTxtWidth:Float(text:String)
		Return GetTxtWidth(text, 1, text.Length)
	End

	#rem monkeydoc 
		This method returns the width in graphic units of the given substring.
		This function will take fromChar and toChar parameters to calculate the substring metrics
	#end
	Method GetTxtWidth:Float(text:String, fromChar:Int, toChar:Int)

		Local twidth:Float
		Local MaxWidth:Float = 0
		Local char:Int
		Local lastchar:Int = 0
				
		For Local i:Int = fromChar To toChar
			char = text[i-1]
			If char >= 0 And char < faceChars.Length() and char<> 10 And char<>13 Then
				If faceChars[char] <> Null Then
					lastchar = char
					twidth = twidth + faceChars[char].drawingMetrics.drawingWidth + Kerning.x
				End If
			ElseIf char = 10 
				If Abs(MaxWidth)<Abs(twidth) Then MaxWidth = twidth - Kerning.x  - faceChars[lastchar].drawingMetrics.drawingWidth + faceChars[lastchar].drawingMetrics.drawingSize.x
				twidth = 0
				lastchar = char
			End If
		Next
		If lastchar >= 0 And lastchar < faceChars.Length() Then
			if lastchar = 32 then
				'Do nothing. We let the spacing at the end of the string.
			ElseIf faceChars[lastchar] <> Null Then
				twidth = twidth - faceChars[lastchar].drawingMetrics.drawingWidth 
				twidth = twidth + faceChars[lastchar].drawingMetrics.drawingSize.x 
			End If		
		End If
		If Abs(MaxWidth)<Abs(twidth ) Then MaxWidth = twidth - Kerning.x  '- faceChars[lastchar].drawingMetrics.drawingWidth + faceChars[lastchar].drawingMetrics.drawingSize.x
		Return MaxWidth 'twidth
	End Method
	
	#rem monkeydoc
		This method returns the height in graphic units of the given string.
	#end
	Method GetTxtHeight:Float(Text:String)
		'Too agreesive as it generates an array, but it is simple in calculation:
		'return (Text.Split("~n").Length + 1) * (faceChars[32].drawingMetrics.drawingSize.y + Kerning.y) 
		
		'Alternative:
		Local count:int = 0
		For Local i=0 until Text.Length
			if Text[i] = 10 Then
				count+=1
			EndIf
		Next
		Return count * (faceChars[32].drawingMetrics.drawingSize.y + Kerning.y) + GetFontHeight()
	End
	
	#rem monkeydoc
		This method returns the height in pixels of the font.
	#end
	Method GetFontHeight:Int() 
		If faceChars[32] = Null Then Return 0
		Return faceChars[32].drawingMetrics.drawingSize.y 
	End Method
	
	#rem monkeydoc
		This method returns the drawing char info of the given face character.
	#end
	Method GetFaceInfo:BitMapCharMetrics(char:Int)
		if char>=0 And char<faceChars.Length() Then
			if faceChars[char] <> null Then Return faceChars[char].drawingMetrics Else Return null
		End
	End
	
	#rem monkeydoc
		This method returns the drawing char info of the given border character.
	#end
	Method GetBorderInfo:BitMapCharMetrics(char:Int)
		if char>=0 And char<borderChars.Length() Then
			if borderChars[char] <> null Then Return borderChars[char].drawingMetrics Else Return null
		End
	End
	
	#rem monkeydoc
		This method returns the drawing char info of the given shadow character.
	#end
	Method GetShadowInfo:BitMapCharMetrics(char:Int)
		if char>=0 And char<shadowChars.Length() Then
			if shadowChars[char] <> null Then Return shadowChars[char].drawingMetrics Else Return null
		End
	End
	
	#rem monkeydoc
		This method returns the rectangle coordinates of the given char into the packed texture.
		This method returns phisical coordinates in the texture, in pixels.
	#end
	Method GetPackedFaceRectangle:DrawingRectangle(char:Int)
		if char>=0 And char<faceChars.Length() Then
			Local rect := new drawingrectangle.DrawingRectangle 
			if faceChars[char] = null Then Return rect
			rect.x = faceChars[char].packedPosition.x
			rect.y = faceChars[char].packedPosition.y
			rect.width = faceChars[char].packedSize.x
			rect.height = faceChars[char].packedSize.y 
			Return rect
		End		
	End Method

	#rem monkeydoc
		This method returns the rectangle coordinates of the given char shadow into the packed texture.
		This method returns phisical coordinates in the texture, in pixels.
	#end
	Method GetPackedShadowRectangle:DrawingRectangle(char:Int)
		if char>=0 And char<shadowChars.Length() Then
			Local rect := new drawingrectangle.DrawingRectangle 
			if shadowChars[char] = null Then Return rect
			rect.x = shadowChars[char].packedPosition.x
			rect.y = shadowChars[char].packedPosition.y
			rect.width = shadowChars[char].packedSize.x
			rect.height = shadowChars[char].packedSize.y 
			Return rect
		End		
	End Method

	#rem monkeydoc
		This method returns the rectangle coordinates of the given char border into the packed texture.
		This method returns phisical coordinates in the texture, in pixels.
	#end
	Method GetPackedBorderRectangle:DrawingRectangle(char:Int)
		if char>=0 And char<borderChars.Length() Then
			Local rect := new drawingrectangle.DrawingRectangle 
			if borderChars[char] = null Then Return rect
			rect.x = borderChars[char].packedPosition.x
			rect.y = borderChars[char].packedPosition.y
			rect.width = borderChars[char].packedSize.x
			rect.height = borderChars[char].packedSize.y 
			Return rect
		End		
	End Method

	#rem monkeydoc
		This method returns True if the current font is a packed font. Otherwise it returns false.
	#end
	Method IsPacked:Bool()
		'if packedImages = null Then Return False
		if packedImages.Length = 0 Then Return False
		Return true
	End Method

	#rem monkeydoc
		This method will force a dynamic font to load all the available characters.
	#end
	Method LoadFullFont()
		if faceChars.Length >0 then
			For local ch:BitMapChar = EachIn faceChars
				if ch<>null then ch.LoadCharImage()
			Next
		endif
		if borderChars.Length >0 then
			For local ch:BitMapChar = EachIn borderChars 
				if ch<>null then ch.LoadCharImage()
			Next
		endif
		if shadowChars.Length >0 then
			For local ch:BitMapChar = EachIn shadowChars
				if ch<>null then ch.LoadCharImage()
			Next
		endif
	End
	
	#rem monkeydoc
		This method will force a dynamic font to unload all its characters.
	#end
	Method UnloadFullFont()
		if faceChars.Length >0 then
			For local ch:BitMapChar = EachIn faceChars
				if ch<>null then ch.UnloadCharImage()
			Next
		endif
		if borderChars.Length >0 then
			For local ch:BitMapChar = EachIn borderChars 
				if ch<>null then ch.UnloadCharImage()
			Next
		endif
		if shadowChars.Length >0 then
			For local ch:BitMapChar = EachIn shadowChars
				if ch<>null then ch.UnloadCharImage()
			Next
		endif
	End	
	
	#rem monkeydoc
		This method will force a dynamic font to load all the characters required to draw the given string on the graphics canvas.
	#end
	Method LoadCharsForText(text:String)
		For Local i:Int = 1 to text.Length 
			Local char:Int = text[i-1]
			if char>=0 And char<=faceChars.Length Then
				If faceChars[char] <> null Then faceChars[char].LoadCharImage()
			EndIf
			if char>=0 And char<=borderChars.Length Then
				If borderChars[char] <> null Then borderChars[char].LoadCharImage()
			EndIf
			if char>=0 And char<=shadowChars.Length Then
				If shadowChars[char] <> null Then shadowChars[char].LoadCharImage()
			EndIf
		Next

	End
	
	#rem monkeydoc
		This method will force a dynamic font to unload all the characters in the given string.
	#end
	Method UnloadCharsForText(text:String)
			For Local i:Int = 1 to text.Length 
			Local char:Int = text[i-1]			
			if char>=0 And char<=faceChars.Length Then 
				If faceChars[char] <> null Then faceChars[char].UnloadCharImage()
			EndIf
			if char>=0 And char<=borderChars.Length Then
				If borderChars[char] <> null Then borderChars[char].UnloadCharImage()
			EndIf
			if char>=0 And char<=shadowChars.Length Then
				If shadowChars[char] <> null Then shadowChars[char].UnloadCharImage()
			EndIf
		Next

	End
		
	Private
	
	Field _drawShadow:Bool = true
	Field _drawBorder:Bool = true
	Field borderChars:BitMapChar[]
	Field faceChars:BitMapChar[]
	Field shadowChars:BitMapChar[]
		
	Method LoadFontData(Info:String, fontName:String, dynamicLoad:bool )
		if Info.StartsWith("P1") Then
			LoadPacked(Info,fontName,dynamicLoad)				
			return
		EndIf
		Local tokenStream:String[] = Info.Split(",") 
		local index:Int = 0 
		borderChars = New BitMapChar[65536]
		faceChars = New BitMapChar[65536]
		shadowChars = New BitMapChar[65536]
		
		Local prefixName:String = fontName
		if prefixName.ToLower().EndsWith(".txt") Then prefixName = prefixName[..-4]
		
		Local char:Int = 0
		while index<tokenStream.Length
			'We get char to load:
			Local strChar:String = tokenStream[index]
			if strChar.Trim() = "" Then 
				'Print "This is going to fail..."
				index+=1
				Exit    
			endif
			char = int(strChar)
			'Print "Loading char: " + char + " at index: " + index
			index+=1
			
			Local kind:String = tokenStream[index]
			'Print "Found kind= " + kind 
			index +=1
			
			Select kind
				Case "{BR"
					index+=3 '3 control point for future use
					borderChars[char] = New BitMapChar
					borderChars[char].drawingMetrics.drawingOffset.x = Int(tokenStream[index])
					borderChars[char].drawingMetrics.drawingOffset.y = Int(tokenStream[index+1])
					borderChars[char].drawingMetrics.drawingSize.x = Int(tokenStream[index+2])
					borderChars[char].drawingMetrics.drawingSize.y = Int(tokenStream[index+3])
					borderChars[char].drawingMetrics.drawingWidth = Int(tokenStream[index+4])
					if dynamicLoad  = False then
						borderChars[char].image = LoadImage(prefixName + "_BORDER_" + char + ".png")
						borderChars[char].image.SetHandle(-borderChars[char].drawingMetrics.drawingOffset.x,-borderChars[char].drawingMetrics.drawingOffset.y)
					Else
						borderChars[char].SetImageResourceName  prefixName + "_BORDER_" + char + ".png"
					endif
					index+=5
					index+=1 ' control point for future use

				Case "{SH"
					index+=3 '3 control point for future use
					shadowChars[char] = New BitMapChar
					shadowChars[char].drawingMetrics.drawingOffset.x = Int(tokenStream[index])
					shadowChars[char].drawingMetrics.drawingOffset.y = Int(tokenStream[index+1])
					shadowChars[char].drawingMetrics.drawingSize.x = Int(tokenStream[index+2])
					shadowChars[char].drawingMetrics.drawingSize.y = Int(tokenStream[index+3])
					shadowChars[char].drawingMetrics.drawingWidth = Int(tokenStream[index+4])
					Local filename:String = prefixName + "_SHADOW_" + char + ".png"
					if dynamicLoad  = False then
						shadowChars[char].image = LoadImage(filename)
						shadowChars[char].image.SetHandle(-shadowChars[char].drawingMetrics.drawingOffset.x,-shadowChars[char].drawingMetrics.drawingOffset.y)
					Else
						shadowChars[char].SetImageResourceName  filename 
					endif

					
					'shadowChars[char].image = LoadImage(filename)
					'shadowChars[char].image.SetHandle(-shadowChars[char].drawingMetrics.drawingOffset.x,-shadowChars[char].drawingMetrics.drawingOffset.y)

					index+=5
					index+=1 ' control point for future use
					
				Case "{FC"
					index+=3 '3 control point for future use
					faceChars[char] = New BitMapChar
					faceChars[char].drawingMetrics.drawingOffset.x = Int(tokenStream[index])
					faceChars[char].drawingMetrics.drawingOffset.y = Int(tokenStream[index+1])
					faceChars[char].drawingMetrics.drawingSize.x = Int(tokenStream[index+2])
					faceChars[char].drawingMetrics.drawingSize.y = Int(tokenStream[index+3])
					faceChars[char].drawingMetrics.drawingWidth = Int(tokenStream[index+4])
					if dynamicLoad = False then
						faceChars[char].image = LoadImage(prefixName + "_" + char + ".png")
						faceChars[char].image.SetHandle(-faceChars[char].drawingMetrics.drawingOffset.x,-faceChars[char].drawingMetrics.drawingOffset.y)
					Else
						faceChars[char].SetImageResourceName prefixName + "_" + char + ".png" 
					endif
					index+=5 
					index+=1 ' control point for future use

				Default 
				Print "Error loading font! Char = " + char
				
			End
		Wend
		borderChars = borderChars[..char+1]
		faceChars = faceChars[..char+1]
		shadowChars = shadowChars[..char+1]
	End
	
	Field packedImages:Image[]
	
	Method LoadPacked(info:String, fontName:String, dynamicLoad:bool )

		Local header:String = info[.. info.Find(",")]
		
		Local separator:String
		Select header
			Case "P1"
				separator = "."
			Case "P1.01"
				separator = "_P_"
		End Select
		info = info[info.Find(",")+1..]
		borderChars = New BitMapChar[65536]
		faceChars = New BitMapChar[65536]
		shadowChars = New BitMapChar[65536]
		packedImages = New Image[256]
		Local maxPacked:Int = 0
		Local maxChar:Int = 0

		Local prefixName:String = fontName
		if prefixName.ToLower().EndsWith(".txt") Then prefixName = prefixName[..-4]

		Local charList:string[] = info.Split(";")
		For local chr:String = EachIn charList

			Local chrdata:string[] = chr.Split(",")
			if chrdata.Length() <2 Then Exit 
			Local char:bitmapchar.BitMapChar 
			Local charIndex:Int = int(chrdata[0])
			if maxChar<charIndex Then maxChar = charIndex 
			
			select chrdata[1]
				Case "B"
					borderChars[charIndex] = New BitMapChar
					char = borderChars[charIndex]
				Case "F"
					faceChars [charIndex] = New BitMapChar
					char = faceChars[charIndex]
				Case "S"
					shadowChars [charIndex] = New BitMapChar
					char = shadowChars[charIndex]
			End Select
			char.packedFontIndex = Int(chrdata[2])
			if packedImages[char.packedFontIndex] = null Then
				packedImages[char.packedFontIndex] = LoadImage(prefixName + separator + char.packedFontIndex +  ".png")
				if maxPacked<char.packedFontIndex Then maxPacked = char.packedFontIndex
			endif
			char.packedPosition.x = Int(chrdata[3])
			char.packedPosition.y = Int(chrdata[4])
			char.packedSize.x = Int(chrdata[5])
			char.packedSize.y = Int(chrdata[6])
			char.drawingMetrics.drawingOffset.x = Int(chrdata[8])
			char.drawingMetrics.drawingOffset.y = Int(chrdata[9])
			char.drawingMetrics.drawingSize.x = Int(chrdata[10])
			char.drawingMetrics.drawingSize.y = Int(chrdata[11])
			char.drawingMetrics.drawingWidth = Int(chrdata[12])

		Next
		borderChars = borderChars[..maxChar+1]
		faceChars = faceChars[..maxChar+1]
		shadowChars = shadowChars[..maxChar+1]
		packedImages = packedImages[..maxPacked+1]
		
	end
	
	Method DrawCharsText(text:String, x:Float, y:Float, mode:Int = eDrawMode.FACE, align:Int, init:Int, ending:Int)
		If mode = eDrawMode.BORDER  Then
			DrawCharsText(text, x, y, borderChars, align, init, ending)
		ElseIf mode = eDrawMode.FACE  Then
			DrawCharsText(text, x, y, faceChars, align, init, ending)
		Else
			DrawCharsText(text, x, y, shadowChars, align, init, ending)
		EndIf
	End


	Const lineSep:String = "~n"
	
	Method DrawCharsText(text:String, x:Float, y:Float, target:BitMapChar[], align:Int, startPos:Int = 1, endPos:Int = - 1)
		Local drx:Int = x, dry:Int = y
		Local oldX:Int = x
		Local xOffset:Int = 0
		'Local lineSep:String = String.FromChar(10)
		if endPos = - 1 or endPos > text.Length Then
			endPos = text.Length
		end
		If align <> eDrawAlign.LEFT Then
			Local lineSepPos:Int = 0
			If endPos <> - 1 Then lineSepPos = endPos Else lineSepPos = text.Find(lineSep, startPos)
			
			If lineSepPos < 0 or lineSepPos > endPos Then lineSepPos = endPos
			Select align
				Case eDrawAlign.CENTER ; xOffset = Self.GetTxtWidth(text, startPos, lineSepPos) / 2 'Forcing an INT is a good idea to prevent drawing rounding artifacts... ¿?
				Case eDrawAlign.RIGHT ;  xOffset = Self.GetTxtWidth(text, startPos, lineSepPos)
			End Select
		EndIf
		
		For Local i:Int = startPos to endPos 'text.Length
			Local char:Int = text[i-1]
			if char>=0 And char<=target.Length Then
				if char = 10 Then
					dry += Int(faceChars[32].drawingMetrics.drawingSize.y) + Kerning.y
					Self.DrawCharsText(text, oldX, dry, target, align, i + 1, endPos)
					return
				ElseIf target[char] <> null Then
					if target[char].CharImageLoaded() = false Then
						target[char].LoadCharImage()
					End
					if target[char].image <> null Then
						DrawImage(target[char].image,drx-xOffset,dry)
					ElseIf target[char].packedFontIndex > 0 Then
						DrawImageRect(packedImages[target[char].packedFontIndex],-xOffset+drx+target[char].drawingMetrics.drawingOffset.x,dry+target[char].drawingMetrics.drawingOffset.y,target[char].packedPosition.x,target[char].packedPosition.y,target[char].packedSize.x,target[char].packedSize.y)
					Endif
					drx+=faceChars[char].drawingMetrics.drawingWidth  + Kerning.x
				endif
			Else
			'	Print "Char " + char + " out of scope."
			EndIf
		Next
	End
				
	Private

	Field _kerning:drawingpoint.DrawingPoint 
	Public
	#rem monkeydoc
		This property allows you to define additional kerning on a given bitmap font.
		By using this property, you set the horizonal and vertical kerning that has to be added on any draw operation.
		This information will be expressed in the form of a DrawingPoint instance.
	#end
	Method Kerning:drawingpoint.DrawingPoint() property
		if _kerning = null Then _kerning = New drawingpoint.DrawingPoint
		Return _kerning
	End

	Method Kerning:void(value:drawingpoint.DrawingPoint) property
		_kerning = value		  
			
	End
		
End

